OpenCV 您所在的位置:网站首页 halcon 自动阈值分割 OpenCV

OpenCV

2024-02-18 16:55| 来源: 网络整理| 查看: 265

阈值分割

目的是从灰度图像中分离出目标区域和背景区域,应该使得前景区的平均灰度、背景区灰度的平均值与整幅图的平均灰度之间的差异最大。图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

大于阈值得像素设为白色(255),小于&等于阈值得像素设为黑色(0)(也可以反过来)。

retval, dst = cv2.threshold( src, thresh, maxval, type[, dst] )THRESH_TRIANGLETHRESH_OTSUcv2.adaptiveThreshold(src, dst, maxValue, adaptiveMethod, teresholdType, blocksize, C)threshTwoPeaks(image)threshEntropy(image)

 

1.全局阈值分割

降噪,过滤很小或很大像素值的图像点。

大于阈值得像素设为白色,小于&等于阈值得像素设为黑色(也可以反过来)。

retval, dst = cv2.threshold( src, thresh, maxval, type[, dst] )

retval:返回计算后的阈值

src:原图像,单通道矩阵,CV_8U&CV_32F

dst:结果图像

thresh:当前阈值

maxVal:最大阈值,一般为255

thresholdType:阈值类型,主要有下面几种:

THRESH_BINARY:二进制阈值。大于阈值的像素=maxVal,小于&等于阈值的像素=0(value>threshold?255:0)THRESH_BINARY_INV:反二进制阈值。大于阈值的像素=0,小于&等于阈值的像素=maxVal (value>threshold?0:255)  THRESH_TRUNC:截断阈值。大于阈值的像素=阈值,小于&等于阈值的像素=不变 (value>threshold?threshold:value)THRESH_TOZERO:阈值化为0。大于阈值的像素=不变,小于&等于阈值得像素=0 (value>threshold?value:0)  THRESH_TOZERO_INV:反阈值化为0。大于阈值的像素=0,小于&等于阈值得像素=不变 (value>threshold?0:value) 

注:THRESH_OTSU和THRESH_TRIANGLE是作为优化算法配合

THRESH_BINARY、THRESH_BINARY_INV、THRESH_TRUNC、THRESH_TOZERO&THRESH_TOZERO_INV来使用的。

当使用了THRESH_OTSU和THRESH_TRIANGLE两个标志时,输入图像必须为单通道。

#全局阈值分割 #threshold(src(单通道矩阵,CV_8U&CV_32F), dst, thresh(阈值), maxVal(在图像二值化显示时,一般=为255), type) #大于阈值得像素=maxVal,小于&等于阈值得像素=0 (type=THRESH_BINARY) #大于阈值得像素=0,小于&等于阈值得像素=maxVal (type=THRESH_BINARY_INV) #当(type=THRESH_OTSU & type=THRESH_TRIANGLE(3.x新特性))时,会自动计算阈值。 #当(type=THRESH_OTSU + THRESH_BINARY)时,即先用THRESH_OTSU自动计算出阈值,然后利用该阈值采用THRESH_BINARY规则(默认)。 import cv2 import numpy as np src = np.array([[123,234,68], [33,51,17], [48,98,234], [129,89,27], [45,167,134]],np.uint8) #手动设置阈值 the = 150 maxval = 255 the, dst = cv2.threshold(src, the, maxval, cv2.THRESH_BINARY_INV) print (the) print (dst) #Otsu阈值处理 otsuThe = 0 otsuThe, dst_Otsu = cv2.threshold(src, otsuThe, maxval, cv2.THRESH_OTSU) print (otsuThe) print (dst_Otsu) #TRIANGLE阈值处理 triThe = 0 triThe, dst_tri = cv2.threshold(src, triThe, maxval, cv2.THRESH_TRIANGLE + cv2.THRESH_BINARY_INV) print (triThe) print (dst_tri)

2.THRESH_TRIANGLE优化算法

当(type=THRESH_TRIANCLE + THRESH_BINARY)时,即先用THRESH_TRIANGLE自动计算出阈值,然后利用该阈值采用THRESH_BINARY规则(默认)。

import cv2 #TRIANGLE阈值处理 src = cv2.imread(r'C:\Users\x\Desktop\OpenCV-Pic\6\img7.jpg', cv2.IMREAD_GRAYSCALE) triThe = 0 maxval = 255 triThe, dst_tri = cv2.threshold(src, triThe, maxval, cv2.THRESH_TRIANGLE + cv2.THRESH_BINARY) triThe1, dst_tri1 = cv2.threshold(src, triThe, maxval, cv2.THRESH_TRIANGLE + cv2.THRESH_BINARY_INV) print (triThe) print (triThe1) cv2.imshow("image", src) cv2.imshow('thresh_out', dst_tri) cv2.imshow('thresh_out1', dst_tri1) cv2.waitKey(0) cv2.destroyAllWindows()

3.THRESH_OTSU优化算法

Otsu提出最大方差法 在判别分析最小二乘法原理的基础上推导而来

import cv2 #TRIANGLE阈值处理 src = cv2.imread(r'C:\Users\x\Desktop\OpenCV-Pic\6\img7.jpg', cv2.IMREAD_GRAYSCALE) triThe = 0 maxval = 255 triThe, dst_tri = cv2.threshold(src, triThe, maxval, cv2.THRESH_OTSU + cv2.THRESH_BINARY) triThe1, dst_tri1 = cv2.threshold(src, triThe, maxval, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV) print (triThe) print (triThe1) cv2.imshow("image", src) cv2.imshow('thresh_out', dst_tri) cv2.imshow('thresh_out1', dst_tri1) cv2.waitKey(0) cv2.destroyAllWindows()

4.自适应阈值分割

区域(局部)自适应二值化 计算大概过程是为每一个象素点单独计算的阈值,即每个像素点的阈值都是不同的,就是将该像素点周围B*B区域内的像素加权平均,然后减去一个常数C,从而得到该点的阈值。

针对每个位置的灰度值设置一个对应的阈值,而该位置的阈值的设置和其邻域有必然的关系。 可以使用平滑处理后的输出结果作为每个像素设置阈值的参考值。 一般,平滑算子的宽度必须大于被识别的物体的宽度。

优点:

在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。

cv2.adaptiveThreshold(src, dst, maxValue, adaptiveMethod, teresholdType, blocksize, C)

src:要二值化的灰度图

dst:二值化后的图

maxValue:一般取255

adaptiveMethod:块计算的方法

ADAPTIVE_THRESH_MEAN_C(均值平滑),为局部邻域块的平均值。该算法是先求出块中的均值,再减去常数C。ADAPTIVE_THRESH_GAUSSIAN_C(高斯平滑),为局部邻域块的高斯加权和。该算法是在区域中(x,y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算, 再减去常数C。

teresholdTypt:二值化类型

THRESH_BINARYTHRESH_BINARY_INV

blocksize:平滑算子尺寸为奇数

C:系数

import cv2 img = cv2.imread(r'C:\Users\x\Desktop\OpenCV-Pic\6\img4.jpg', cv2.IMREAD_GRAYSCALE) dst = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 43, 0.15) cv2.imshow("image", img) cv2.imshow('thresh_out', dst) cv2.waitKey(0) cv2.destroyAllWindows()

5.直方图技术法

直方图技术法就是首先找到这两个峰值,然后取这两个峰值之间得波谷位置对应得灰度值,就是所要得阈值。

在有明显波峰的图像的阈值处理效果好。

import cv2 import numpy as np def caleGrayHist(image): #灰度图像的高、宽 rows, cols = image.shape #存储灰度直方图 grayHist = np.zeros([256], np.uint64) #图像的灰度级范围是0~255 for r in range(rows): for c in range(cols): grayHist[image[r][c]] += 1 return grayHist def threshTwoPeaks(image): #计算灰度直方图 histogram = caleGrayHist(image) #找到灰度直方图的最大峰值对应得灰度值 maxLoc = np.where(histogram==np.max(histogram)) firstPeak = maxLoc[0][0] #取第一个最大的灰度值 #寻找灰度直方图的第二个峰值对应得灰度值 measureDists = np.zeros([256], np.float32) for k in range(256): measureDists[k] = pow(k-firstPeak,2)*histogram[k] maxLoc2 = np.where(measureDists==np.max(measureDists)) secondPeak = maxLoc2[0][0] #找到两个峰值之间的最小值对应的灰度值,作为阈值 thresh = 0 if firstPeak > secondPeak: #第一个峰值在第二个峰值右侧 temp = histogram[int(secondPeak):int(firstPeak)] minLoc = np.where(temp==np.min(temp)) thresh = secondPeak + minLoc[0][0] + 1 #有多个波谷取左侧的波谷 else: temp = histogram[int(firstPeak):int(secondPeak)] minLoc = np.where(temp==np.min(temp)) thresh = firstPeak + minLoc[0][0] + 1 #找到阈值后进行阈值处理,得到二值图 threshImage_out = image.copy() threshImage_out[threshImage_out > thresh] = 255 threshImage_out[threshImage_out thresh] = 255 threshold[threshold


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有